/* 
 * File:   DTATriangulo.h
 * Author: fozut
 *
 * Created on 21 de Dezembro de 2009, 14:29
 */

#ifndef _DTATRIANGULO_H
#define	_DTATRIANGULO_H


#include "DTAStructBase.h"
#include "DTAPonto.h"
#include <iostream>


using namespace std;




class DTATriangulo: public DTAStructBase
{
public:
    DTATriangulo();
    ~DTATriangulo();
    void print();
    inline int toHash(int sizeHash);
    const DTAPonto* getIncentro();
    void alterPoint(DTAPonto oldPoint, DTAPonto newPoint);


    bool operator < (DTATriangulo tr);
    bool operator <= (DTATriangulo tr);
    bool operator > (DTATriangulo tr);
    bool operator >= (DTATriangulo tr);

    bool operator == (DTATriangulo tr);
    bool operator != (DTATriangulo tr);

    DTAPonto p1;
    DTAPonto p2;
    DTAPonto p3;

    
private:
    DTAPonto *incentro;

    inline double avalFunc()
    {
        getIncentro();
        double incX;
        double incY;
        double incZ;
        incX = incentro->x;
        incY = incentro->y;
        incZ = incentro->z;
        return 3.0*incX*incX*incX + 5.0*incY*incY*incY*incY*incY + 7.0*incZ*incZ*incZ*incZ*incZ*incZ*incZ;
    }
    
   
};

DTATriangulo::DTATriangulo()
{
    incentro = new DTAPonto;
    
};

DTATriangulo::~DTATriangulo()
{
    
};

inline int DTATriangulo::toHash(int sizeHash)
{
    int mod;
    const DTAPonto* inc;
    double incX;
    double incY;
    double incZ;

    inc = getIncentro();

    incX = inc->x;
    incY = inc->y;
    incZ = inc->z;

    incX *=1000;
    incY *=1000;
    incZ *=1000;

 
    mod = fmod(3.0*incX*incX*incX + 5.0*incY*incY*incY*incY*incY* + 7.0*incZ*incZ*incZ*incZ*incZ*incZ*incZ,sizeHash);

    if (mod <0) mod = (-1)*mod;
    return mod;
};

void DTATriangulo::print()
{
    getIncentro();
    cout.precision(20);
    if( active==true )
    {
        cout << "ID do tr: " << id << endl;

        cout <<"pontos: "<<endl;
        cout << "\t" ;
        p1.print();
        cout << "\t" ;
        p2.print();
        cout << "\t" ;
        p3.print();
        cout <<"Incentro: "<<endl;
        cout << "\t" ;
        incentro->print();
    }
    else
    {
        cout << "Erro ao imprimir triangulo; triangulo inativo" << endl;
    }
};

const DTAPonto* DTATriangulo::getIncentro()
{
    double tamAr0;
    double tamAr1;
    double tamAr2;
    double sumAr;

    //  return sqrt((ar.p0.x - ar.p1.x)*(ar.p0.x - ar.p1.x) + (ar.p0.y - ar.p1.y)*(ar.p0.y - ar.p1.y) + (ar.p0.z - ar.p1.z)*(ar.p0.z - ar.p1.z));

    tamAr0 = sqrt( pow(p1.x - p2.x,2) + pow(p1.y - p2.y,2) + pow(p1.z - p2.z,2) );
    tamAr1 = sqrt( pow(p2.x - p3.x,2) + pow(p2.y - p3.y,2) + pow(p2.z - p3.z,2) );
    tamAr2 = sqrt( pow(p3.x - p1.x,2) + pow(p3.y - p1.y,2) + pow(p3.z - p1.z,2) );

  //  cout << "tamanho das aresta: " << tamAr0 << " " << tamAr1 << " " << tamAr2 << endl;

    sumAr = tamAr0 + tamAr1 + tamAr2;

   // cout << "sumAR: " << sumAr << endl;

    incentro->x = p1.x*tamAr1/sumAr + p2.x*tamAr2/sumAr + p3.x*tamAr0/sumAr;
    incentro->y = p1.y*tamAr1/sumAr + p2.y*tamAr2/sumAr + p3.y*tamAr0/sumAr;
    incentro->z = p1.z*tamAr1/sumAr + p2.z*tamAr2/sumAr + p3.z*tamAr0/sumAr;

    
    return incentro;
}

bool DTATriangulo::operator <(DTATriangulo tr)
{
    

     if(  trunc(avalFunc()*100000) < trunc(tr.avalFunc()*100000) )
        return true;
    else
        return false;
};

bool DTATriangulo::operator <=(DTATriangulo tr)
{
    

     if(  trunc(avalFunc()*100000) <= trunc(tr.avalFunc()*100000) )//if( ( trunc(2.0*pow(incLocal->x,2) + 3.0*pow(incLocal->y,3) + 5.0*pow(incLocal->z,5))*100000) <= trunc((2.0*pow(incParam->x,2) + 3.0*pow(incParam->y,3) + 5.0*pow(incParam->z,5))*100000) )
        return true;
    else
        return false;
};

bool DTATriangulo::operator >(DTATriangulo tr)
{
    const DTAPonto *incLocal;
    const DTAPonto *incParam;

    incLocal = getIncentro();
    incParam = tr.getIncentro();

     if(  trunc(avalFunc()*100000) > trunc(tr.avalFunc()*100000) )//if( ( trunc(2.0*pow(incLocal->x,2) + 3.0*pow(incLocal->y,3) + 5.0*pow(incLocal->z,5))*100000) > trunc((2.0*pow(incParam->x,2) + 3.0*pow(incParam->y,3) + 5.0*pow(incParam->z,5))*100000) )
        return true;
    else
        return false;
};

bool DTATriangulo::operator >=(DTATriangulo tr)
{
    const DTAPonto *incLocal;
    const DTAPonto *incParam;

    incLocal = getIncentro();
    incParam = tr.getIncentro();

     if(  trunc(avalFunc()*100000) >= trunc(tr.avalFunc()*100000) )//if( ( trunc(2.0*pow(incLocal->x,2) + 3.0*pow(incLocal->y,3) + 5.0*pow(incLocal->z,5))*100000) >= trunc((2.0*pow(incParam->x,2) + 3.0*pow(incParam->y,3) + 5.0*pow(incParam->z,5))*100000) )
        return true;
    else
        return false;
};

bool DTATriangulo::operator !=(DTATriangulo tr)
{
    if( (p1 != tr.p1 && p1!=tr.p2 && p1 !=tr.p3 ) || (p2 != tr.p1 && p2 != tr.p2 && p2 !=tr.p3) || (p3 !=tr.p1 && p3 != tr.p2 && p3 != tr.p3)) //os ponteiros apontam pro mesmo local
        return true;
    else
        return false;
};

bool DTATriangulo::operator ==(DTATriangulo tr)
{
    const DTAPonto *incLocal;
    const DTAPonto *incParam;

   
    if( (p1 == tr.p1 || p1==tr.p2 || p1 ==tr.p3 )&& (p2 == tr.p1 || p2 == tr.p2 || p2 ==tr.p3) && (p3 ==tr.p1 || p3 == tr.p2 || p3 == tr.p3) )//trunc(incLocal->x*100) == trunc(incParam->x*100) && trunc(incLocal->y*100) == trunc(incParam->y*100) && trunc(incLocal->z*100) == trunc(incParam->z*100) )//(
        return true;
    else
        return false;
};

void DTATriangulo::alterPoint(DTAPonto oldPoint, DTAPonto newPoint)
{
    
    if( p1 == oldPoint)
        p1 = newPoint;
    
        if(p2 == oldPoint)
            p2 = newPoint;
        
            if(p3 == oldPoint)
                p3 = newPoint;
        getIncentro();
}
#endif	/* _DTATRIANGULO_H */
